#include <all_wlib.h>
#pragma hdrstop

#include "ghed_int.h"

GH615_StringDump dump;

//---------------------------------------------------------------------------
//  TextArray
//---------------------------------------------------------------------------
bool TextArray::Save( CONSTSTR fnm, long off )
  {
     memset( &dump, 0, sizeof(dump) );

     DWORD toff = 0;
     int   n;
     for( n = 0; n < Count(); n++ ) {
       PTextItem p = Item(n);

       dump.Offsets[n] = RotateWORD( toff );
       StrCpy( (char*)(&dump.Text[toff]), ToOEM(p->text.c_str()) );

       toff += p->text.Length() + 1;
     }
     dump.Offsets[n] = RotateWORD( toff );

     int f = FIO_OPEN( fnm, O_WRONLY|O_BINARY );
     if ( f == -1 ) return false;

     bool rc = false;
     __try{
       if ( FIO_SEEK( f, off, seekBEGIN ) != off )
         return false;

       if ( FIO_WRITE( f, &dump, sizeof(dump) ) != sizeof(dump) )
         return false;

       rc = true;
     }__finally{
       FIO_CLOSE(f);
     }
 return rc;
}

bool TextArray::Load( CONSTSTR fnm, long off )
  {
     DeleteAll();

     int f = FIO_OPEN( fnm, O_RDONLY|O_BINARY );
     if ( f == -1 ) return false;

     bool rc = false;
     __try{
       if ( FIO_SEEK( f, off, seekBEGIN ) != off )
         return false;

       if ( FIO_READ( f, &dump, sizeof(dump) ) != sizeof(dump) )
         return false;

       for( int n = 0; n < ARRAY_SIZE(dump.Offsets); n++ ) {
         TextItem it;

         if ( n && !dump.Offsets[n] )
           break;

         it.off = RotateWORD( dump.Offsets[ n ] );
         if ( it.off >= sizeof(dump.Text) ) {
           SetError( "Invalid offset data in the file" );
           return false;
         }

         CONSTSTR m = (CONSTSTR)(&dump.Text[ it.off ]);
         if ( !m[0] )
           break;

         int len;
         for( len = 0; m[len] != 0 && len < 128; len++ );
         if ( len >= 128 ) {
           SetError( "Invalid text data in the file" );
           return false;
         }

         it.orig = FromOEM(m);
         it.text = it.orig;

         Add( it );
       }

       rc = true;
     }__finally{
       FIO_CLOSE(f);
     }
     if ( !rc )
       DeleteAll();
 return rc;
}

DWORD TextArray::CalcSize( void )
  {  DWORD cn = 0;
     for( int n = 0; n < Count(); n++ ) {
       PTextItem p = Item(n);
       cn += p->text.Length() + 1;
     }
 return cn;
}
